home *** CD-ROM | disk | FTP | other *** search
- unit EditUndo;
-
- interface
-
- uses
- WinProcs, WinTypes, Messages, SysUtils, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
-
- type
- TEditUndo = class(TEdit)
- private
- { These fields will be initialised to False, an empty }
- { string and zero respectively without any intervention }
-
- { To avoid unwanted calls to our additional code }
- FInternalOverwrite: Boolean;
- { Saved version of old Text property }
- FText: String;
- { Saved version of old SelStart property }
- FSelStart,
- { Saved version of old SelLength property }
- FSelLength,
- { Length of replacement text }
- FReplaceLength: Integer;
- procedure SaveContents(NewText: PChar);
- procedure RestoreContents;
- protected
- { Called if Text property written to }
- procedure WMSetText(var Msg: TMessage);
- message wm_SetText;
- { Called if SelText property written to }
- procedure EMReplaceSel(var Msg: TMessage);
- message em_ReplaceSel;
- { Called when Ctrl-Z pressed }
- procedure EMUndo(var Msg: TMessage);
- message em_Undo;
- end;
-
- procedure Register;
-
- implementation
-
- procedure TEditUndo.SaveContents(NewText: PChar);
- begin
- FText := Text;
- FSelStart := SelStart;
- FSelLength := SelLength;
- { Need to keep record of length of replacement }
- { text to ensure highlighting works when you }
- { repeatedly press the Undo key combination }
- FReplaceLength := StrLen(NewText)
- end;
-
- procedure TEditUndo.RestoreContents;
- var
- TmpText: String;
- begin
- { Need to ensure we can undo the undo }
- { i.e. perform a redo operation }
-
- { Swap saved text with current text }
- TmpText := Text;
- { Writing to Text will generate a wm_SetText message }
- { which we don't want to trap ourselves this time }
- FInternalOverwrite := True;
- Text := FText;
- FText := TmpText;
- FInternalOverwrite := False;
-
- { Restore old highlight}
- SelStart := FSelStart;
- SelLength := FSelLength;
-
- { Update other fields accordingly }
- FSelLength := FReplaceLength;
- FReplaceLength := SelLength;
- end;
-
- procedure TEditUndo.WMSetText(var Msg: TMessage);
- begin
- { The em_Undo property causes this to be called }
- { in addition to external access to Text property. }
- { Avoid doing this saving when not required }
- if not FInternalOverwrite then
- SaveContents(PChar(Msg.LParam));
- inherited;
- end;
-
- procedure TEditUndo.EMReplaceSel(var Msg: TMessage);
- begin
- SaveContents(PChar(Msg.LParam));
- inherited;
- end;
-
- procedure TEditUndo.EMUndo(var Msg: TMessage);
- begin
- { This condition will only be true if we have done }
- { our saving code, cos then the edit says it }
- { cannot undo itself, but FText will have a value }
- if not LongBool(Perform(em_CanUndo, 0, 0)) and
- (FText <> '') then
- RestoreContents
- else
- inherited;
- end;
-
- procedure Register;
- begin
- RegisterComponents('Clinic', [TEditUndo]);
- end;
-
- end.
-